#include <stdio.h>
#include <stdlib.h>

//存储数据元素的最大个数
#define MaxSize 5
#define null 0

/**
 * 队列Queue是具有一定操作约束的线性表
 * 只能在一段插入，在另一端删除（先进后出）
 * 基于数组实现的队列
 */ 
struct QNode{
    int Data[MaxSize];
    int rear;//列尾元素的数组下标
    int front;//列头元素的数组下标
    int number;
};

typedef struct QNode *Queue;

//生成长度为MaxSize的空队列
Queue creatQueue(int size);
//判断队列Q是否已满
int isFullQ(Queue Q);
//循环队列的入队（数组大小为n,但最多放n-1个元素）
void addQ(Queue PtrQ,int item);
//判断队列是否为空
int isEmptyQ(Queue q);
//将队头元素从队列中删除并返回
int deleteQ(Queue PtrQ);
void show(Queue PtrQ);

int main(){
    Queue q = creatQueue(3);
    addQ(q, 1);
    addQ(q, 2);
    deleteQ(q);
    show(q);
    printf("over\n");
    return 0;
}

Queue creatQueue(int size){
    Queue q = (Queue)malloc(sizeof(struct QNode) * size);
    if(q == NULL){
        printf("内存申请失败");
        return q;
    }
    q->front = -1;
    q->rear = -1;
    q->number = 0;
    return q;
}

//关键点：满栈的判定(rear+1)%MaxSize=front
void addQ(Queue PtrQ,int item){
    //先判定队列是否已满
    if(((PtrQ->rear+1) % MaxSize == PtrQ->front)){
        printf("队列满了");
        return;
    }
    PtrQ->rear = (PtrQ->rear+1)%MaxSize;
    PtrQ->Data[PtrQ->rear] = item;
    PtrQ->number++;
}

//关键点:出栈后front的位置 front = (front + 1) % n;
int deleteQ(Queue PtrQ){
    //先判断队列是否为空
    if(PtrQ->rear == PtrQ->front){
        printf("队列为空");
        return null;
    }
    PtrQ->front = (PtrQ->front+1)%MaxSize;
    return PtrQ->Data[PtrQ->front];;
}

void show(Queue q){
    if(q != NULL){
        printf("show:");
        for(int i=0;i<q->number;i++){
            printf(" %d ",q->Data[i]);
        }
        printf("\n");
    }
}

int isEmptyQ(Queue q){
    if(q == NULL){
        printf("队列为空");
        return 1;
    }else{
        return 0;
    }
}